package com.mby.shiro;

import com.mby.entity.Role;
import com.mby.entity.User;
import com.mby.utils.MongoTools;
import com.mby.utils.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by noah on 2018/4/16.
 */
public class ShiroRealm extends AuthorizingRealm {

    //token值
    private String token = "";

    //角色
    private String roleIds;

    //可以执行的操作
    private Integer[] featureIds;

    //用户名
    private String loginName = "";

    MongoTools mongoTool;

    /**
     * 授权用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Set<String> roleNames = new HashSet<String>();
        Set<String> permissions = new HashSet<String>();

        //获取用户角色
        List<?> roles = mongoTool.findMany("","{'id#':'"+roleIds+"'}","", Role.class);
        if(roles != null){
            Role role;String[] functions;
            for(int i=0;i<roles.size();i++){
                role = (Role)roles.get(i);
                //添加角色
                roleNames.add(role.getId().toString());
                functions = role.getFunctions();
                if(functions != null){
                    //添加权限
                    for (int j = 0; j < functions.length; j++) {
                        permissions.add(String.valueOf(functions[j]));
                        System.out.print(functions[j]);
                    }
                }
            }
            System.out.println("");
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
        info.setStringPermissions(permissions);
        return info;
    }

    /**
     * 验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        Subject subject = SecurityUtils.getSubject();String login_type = "";
        try{
            mongoTool = (MongoTools) subject.getSession().getAttribute("mongoTool");
            boolean isMoblie = (Boolean) subject.getSession().getAttribute("isMoblie");
            String tokeName;
            if(isMoblie){
                tokeName = "tokenM";
            }else{
                tokeName = "tokenP";
            }
            subject.getSession().setAttribute("currentUser", null);
            User user;
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authcToken;
            login_type = usernamePasswordToken.getUsername();
            if("login_as".equals(login_type)){
                loginName = String.copyValueOf(usernamePasswordToken.getPassword());
                user = mongoTool.findOne("dealerId,loginName,userName,roleIds,avatarVer,roleName","{'loginName':'"+loginName+"'}",User.class);
            }else{
                token = usernamePasswordToken.getUsername();
                user = mongoTool.findOne("dealerId,loginName,userName,"+tokeName+",roleIds,avatarVer,phone,roleName","{'"+tokeName+"':'"+token+"'}",User.class);
            }

            if (user != null) {
                if(isMoblie){
                    token = user.getTokenM();
                }else{
                    token = user.getTokenP();
                }
                if(token == null){
                    token = SecurityUtil.generate(user.getLoginName() + System.currentTimeMillis());
                    mongoTool.update("{'"+tokeName+"':'"+token+"'}","{'login_name':'"+user.getLoginName()+"'}",User.class);
                }
                roleIds = user.getRoleIds();
                loginName = user.getLoginName();
                subject.getSession().setAttribute("currentUser", user);
                clearCachedAuthorizationInfo(loginName);
                subject.getSession().setAttribute("code", "0");
            }else{
                subject.getSession().setAttribute("code", "Login Required");
            }
        }catch (Exception e){
            e.printStackTrace();
            subject.getSession().setAttribute("code", "Login Required");
        }
        if("login_as".equals(login_type)){
            return new SimpleAuthenticationInfo(loginName, loginName, getName());
        }else{
            return new SimpleAuthenticationInfo(loginName, token, getName());
        }
        //return new SimpleAuthenticationInfo(user, password, getName());*/
    }

    /**
     * 清空某个用户的权限认证缓存
     */
    public void clearCachedAuthorizationInfo(String returnName) {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                if(returnName.equals(key.toString())) {
                    cache.remove(key);
                }
            }
        }
    }
}
